package com.example.project.utils;

import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONArray;
import com.alibaba.fastjson2.JSONObject;
import com.alibaba.fastjson2.JSONWriter;
import com.alibaba.fastjson2.TypeReference;
import com.alibaba.fastjson2.filter.SimplePropertyPreFilter;

import java.util.List;
import java.util.Map;

/**
 * JSON工具类
 * 
 * @author pm-admin
 */
public class JsonUtils {

	/**
	 * 对象转JSON字符串
	 * 
	 * @param object 对象
	 * @return JSON字符串
	 */
	public static String toJsonString(Object object) {
		return JSON.toJSONString(object);
	}

	/**
	 * 对象转JSON字符串（格式化）
	 * 
	 * @param object 对象
	 * @return 格式化的JSON字符串
	 */
	public static String toJsonPrettyString(Object object) {
		return JSON.toJSONString(object, JSONWriter.Feature.PrettyFormat);
	}

	/**
	 * JSON字符串转对象
	 * 
	 * @param jsonString JSON字符串
	 * @param clazz      目标类
	 * @param <T>        泛型
	 * @return 对象
	 */
	public static <T> T parseObject(String jsonString, Class<T> clazz) {
		return JSON.parseObject(jsonString, clazz);
	}

	/**
	 * JSON字符串转复杂对象（支持泛型）
	 * 
	 * @param jsonString    JSON字符串
	 * @param typeReference 类型引用
	 * @param <T>           泛型
	 * @return 对象
	 */
	public static <T> T parseObject(String jsonString, TypeReference<T> typeReference) {
		return JSON.parseObject(jsonString, typeReference);
	}

	/**
	 * JSON字符串转List
	 * 
	 * @param jsonString JSON字符串
	 * @param clazz      列表元素类
	 * @param <T>        泛型
	 * @return List对象
	 */
	public static <T> List<T> parseArray(String jsonString, Class<T> clazz) {
		return JSON.parseArray(jsonString, clazz);
	}

	/**
	 * JSON字符串转JSONObject
	 * 
	 * @param jsonString JSON字符串
	 * @return JSONObject对象
	 */
	public static JSONObject parseObject(String jsonString) {
		return JSON.parseObject(jsonString);
	}

	/**
	 * JSON字符串转JSONArray
	 * 
	 * @param jsonString JSON字符串
	 * @return JSONArray对象
	 */
	public static JSONArray parseArray(String jsonString) {
		return JSON.parseArray(jsonString);
	}

	/**
	 * 对象转Map
	 * 
	 * @param object 对象
	 * @return Map对象
	 */
	public static Map<String, Object> toMap(Object object) {
		String jsonString = toJsonString(object);
		return parseObject(jsonString, new TypeReference<Map<String, Object>>() {
		});
	}

	/**
	 * Map转对象
	 * 
	 * @param map   Map对象
	 * @param clazz 目标类
	 * @param <T>   泛型
	 * @return 对象
	 */
	public static <T> T mapToObject(Map<String, Object> map, Class<T> clazz) {
		String jsonString = toJsonString(map);
		return parseObject(jsonString, clazz);
	}

	/**
	 * 判断字符串是否为有效JSON
	 * 
	 * @param jsonString JSON字符串
	 * @return 是否为有效JSON
	 */
	public static boolean isValidJson(String jsonString) {
		if (StringUtils.isBlank(jsonString)) {
			return false;
		}
		try {
			JSON.parse(jsonString);
			return true;
		} catch (Exception e) {
			return false;
		}
	}

	/**
	 * 判断字符串是否为JSON对象
	 * 
	 * @param jsonString JSON字符串
	 * @return 是否为JSON对象
	 */
	public static boolean isJsonObject(String jsonString) {
		if (!isValidJson(jsonString)) {
			return false;
		}
		try {
			JSON.parseObject(jsonString);
			return true;
		} catch (Exception e) {
			return false;
		}
	}

	/**
	 * 判断字符串是否为JSON数组
	 * 
	 * @param jsonString JSON字符串
	 * @return 是否为JSON数组
	 */
	public static boolean isJsonArray(String jsonString) {
		if (!isValidJson(jsonString)) {
			return false;
		}
		try {
			JSON.parseArray(jsonString);
			return true;
		} catch (Exception e) {
			return false;
		}
	}

	/**
	 * 获取JSON字符串的格式化版本
	 * 
	 * @param jsonString JSON字符串
	 * @return 格式化后的JSON字符串
	 */
	public static String formatJson(String jsonString) {
		if (!isValidJson(jsonString)) {
			return jsonString;
		}
		try {
			Object obj = JSON.parse(jsonString);
			return JSON.toJSONString(obj, JSONWriter.Feature.PrettyFormat);
		} catch (Exception e) {
			return jsonString;
		}
	}

	/**
	 * 对象转JSON字符串（包含指定字段）
	 * 
	 * @param object   对象
	 * @param includes 包含的字段名
	 * @return JSON字符串
	 */
	public static String toJsonStringWithIncludes(Object object, String... includes) {
		SimplePropertyPreFilter filter = new SimplePropertyPreFilter();
		if (includes != null && includes.length > 0) {
			for (String include : includes) {
				filter.getIncludes().add(include);
			}
		}
		return JSON.toJSONString(object, filter);
	}

	/**
	 * 对象转JSON字符串（排除指定字段）
	 * 
	 * @param object   对象
	 * @param excludes 排除的字段名
	 * @return JSON字符串
	 */
	public static String toJsonStringWithExcludes(Object object, String... excludes) {
		SimplePropertyPreFilter filter = new SimplePropertyPreFilter();
		if (excludes != null && excludes.length > 0) {
			for (String exclude : excludes) {
				filter.getExcludes().add(exclude);
			}
		}
		return JSON.toJSONString(object, filter);
	}

	/**
	 * 深度复制对象（通过JSON序列化）
	 * 
	 * @param object 原对象
	 * @param clazz  目标类
	 * @param <T>    泛型
	 * @return 复制后的对象
	 */
	public static <T> T deepCopy(Object object, Class<T> clazz) {
		String jsonString = toJsonString(object);
		return parseObject(jsonString, clazz);
	}

	/**
	 * 合并两个JSON对象
	 * 
	 * @param json1 第一个JSON对象
	 * @param json2 第二个JSON对象
	 * @return 合并后的JSON对象
	 */
	public static JSONObject mergeJson(JSONObject json1, JSONObject json2) {
		JSONObject result = new JSONObject();
		if (json1 != null) {
			result.putAll(json1);
		}
		if (json2 != null) {
			result.putAll(json2);
		}
		return result;
	}

	/**
	 * 从JSON对象中获取指定路径的值
	 * 
	 * @param jsonObject JSON对象
	 * @param path       路径（使用.分隔，如：user.profile.name）
	 * @return 路径对应的值
	 */
	public static Object getValueByPath(JSONObject jsonObject, String path) {
		if (jsonObject == null || StringUtils.isBlank(path)) {
			return null;
		}

		String[] keys = path.split("\\.");
		Object current = jsonObject;

		for (String key : keys) {
			if (current instanceof JSONObject) {
				current = ((JSONObject) current).get(key);
			} else {
				return null;
			}
			if (current == null) {
				return null;
			}
		}
		return current;
	}

	/**
	 * 设置JSON对象中指定路径的值
	 * 
	 * @param jsonObject JSON对象
	 * @param path       路径（使用.分隔）
	 * @param value      要设置的值
	 */
	public static void setValueByPath(JSONObject jsonObject, String path, Object value) {
		if (jsonObject == null || StringUtils.isBlank(path)) {
			return;
		}

		String[] keys = path.split("\\.");
		JSONObject current = jsonObject;

		for (int i = 0; i < keys.length - 1; i++) {
			String key = keys[i];
			if (!current.containsKey(key)) {
				current.put(key, new JSONObject());
			}
			Object next = current.get(key);
			if (next instanceof JSONObject) {
				current = (JSONObject) next;
			} else {
				// 如果路径中间不是对象，则覆盖为对象
				current.put(key, new JSONObject());
				current = current.getJSONObject(key);
			}
		}

		current.put(keys[keys.length - 1], value);
	}

	/**
	 * 将对象转换为JSON字符串并处理null值
	 * 
	 * @param object 对象
	 * @return JSON字符串（null值转为空字符串）
	 */
	public static String toJsonStringHandleNull(Object object) {
		return JSON.toJSONString(object, JSONWriter.Feature.WriteNulls);
	}

}